package cn.sciento.starter.keyencrypt.json;

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import java.util.ArrayList;
import java.util.List;
import cn.sciento.starter.keyencrypt.core.Encrypt;
import cn.sciento.starter.keyencrypt.core.IEncryptionService;

public class EncryptedSerializerModifier extends BeanSerializerModifier {
  private final IEncryptionService encryptionService;
  
  public EncryptedSerializerModifier(IEncryptionService encryptionService) {
    this.encryptionService = encryptionService;
  }
  
  public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDescription, List<BeanPropertyWriter> beanProperties) {
    List<BeanPropertyWriter> newWriters = new ArrayList<>();
    for (BeanPropertyWriter writer : beanProperties) {
      Encrypt encrypt = writer.getAnnotation(Encrypt.class);
      if (null == encrypt) {
        newWriters.add(writer);
        continue;
      } 
      try {
        JsonSerializer<Object> encryptSer = new EncryptedJsonSerializer(this.encryptionService, writer.getSerializer(), encrypt, writer.getType());
        newWriters.add(new EncryptedPropertyWriter(writer, encryptSer));
      } catch (Exception e) {
        e.printStackTrace();
      } 
    } 
    return newWriters;
  }
  
  static class EncryptedPropertyWriter extends BeanPropertyWriter {
    EncryptedPropertyWriter(BeanPropertyWriter base, JsonSerializer<Object> deserializer) {
      super(base);
      this._serializer = deserializer;
    }
  }
}
